package cn.luowb.checkchat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.luowb.checkchat.common.context.UserContext;
import cn.luowb.checkchat.common.result.Result;
import cn.luowb.checkchat.common.util.RedisKeyUtil;
import cn.luowb.checkchat.common.web.Results;
import cn.luowb.checkchat.dao.entity.CommentDO;
import cn.luowb.checkchat.dao.mapper.CommentMapper;
import cn.luowb.checkchat.dao.mapper.PostMapper;
import cn.luowb.checkchat.dao.mapper.UserMapper;
import cn.luowb.checkchat.dto.req.CommentDTO;
import cn.luowb.checkchat.dto.req.CommentPageDTO;
import cn.luowb.checkchat.dto.resp.CommentPageVO;
import cn.luowb.checkchat.dto.resp.CommentVO;
import cn.luowb.checkchat.dto.resp.UserRespDTO;
import cn.luowb.checkchat.service.CommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @author heimenkyou
 * @description 针对表【comment(评论)】的数据库操作Service实现
 * @createDate 2025-09-01 19:07:09
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentDO>
        implements CommentService {
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisKeyUtil redisKeyUtil;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PostMapper postMapper;


    @Override
    public Result<CommentPageVO> queryList(CommentPageDTO commentPageDTO) {
        //运用滚动查询分页
        if (commentPageDTO.getLastTime() == null) {
            commentPageDTO.setLastTime(LocalDateTime.now());
        }
        if (commentPageDTO.getOffset() == null) {
            commentPageDTO.setOffset(0);
        }
        if (commentPageDTO.getSize() == null) {
            commentPageDTO.setSize(3);
        }
        List<CommentDO> list = commentMapper.pageQuery(commentPageDTO);
        if (list == null || list.isEmpty()) {
            CommentPageVO emptyPage = new CommentPageVO();
            emptyPage.setCommentVOS(Collections.emptyList());
            emptyPage.setOffset(0);
            emptyPage.setLastTime(commentPageDTO.getLastTime());
            emptyPage.setCount(0L);
            return Results.success(emptyPage);
        }
        //储存所有评论id
        List<Long> commentIds = list.stream()
                .map(CommentDO::getId)
                .toList();
        //批量查询所有子评论的数量 避免n+1查询
        //原本是想commentid的值为建 count（*）的值为值 则Map为<Long,Long> 但就算声明这样
        //返回的map 任然以列名为键 值为值 所以干脆声明称String 类型
        List<Map<String, Long>> commentCountList = commentMapper.countReplyCount(commentIds);
        System.out.println(commentCountList);
        Map<Long, Long> commentCountMap = new HashMap<>();
        for (Map<String, Long> map : commentCountList) {
            commentCountMap.put(map.get("commentId"), map.get("reply"));
        }
        System.out.println(commentCountMap);
        List<CommentVO> commentVOList = new ArrayList<>();


        Long count = query().count();
        LocalDateTime minTime = null;
        int cou = 0;
        for (CommentDO commentDO : list) {
            if (minTime == null || commentDO.getCreateTime().equals(minTime)) {
                cou++;
                minTime = commentDO.getCreateTime();
            } else {
                minTime = commentDO.getCreateTime();
                cou = 1;
            }
            CommentVO commentVO = BeanUtil.copyProperties(commentDO, CommentVO.class);
            //查询该条评论的子评论有多少条
            Long replyCount = commentCountMap.getOrDefault(commentDO.getId(), 0L);
            commentVO.setCommentCount(replyCount);
            //判断当前用户是否对该评论点赞
            isLiked(commentVO);
            //TODO 根据用户id 查询用户头像等基本信息
            ArrayList<Long> list1 = new ArrayList<>();
            list1.add(commentVO.getUid());
            List<UserRespDTO> userList = userMapper.getUserList(list1);
            commentVO.setUserRespDTO(userList.get(0));
            commentVOList.add(commentVO);
        }
        CommentPageVO commentPageVO = new CommentPageVO();
        commentPageVO.setCommentVOS(commentVOList);
        commentPageVO.setOffset(cou);
        commentPageVO.setLastTime(minTime);
        commentPageVO.setCount(count);
        return Results.success(commentPageVO);
    }

    @Override
    public Result<CommentPageVO> commentReplies(CommentPageDTO commentPageDTO) {
        //处理第一次查询
        if (commentPageDTO.getOffset() == null) {
            commentPageDTO.setOffset(0);
        }
        if (commentPageDTO.getLastTime() == null) {
            commentPageDTO.setLastTime(LocalDateTime.now());
        }
        if (commentPageDTO.getSize() == null) {
            commentPageDTO.setSize(3);
        }
        List<CommentDO> commentDOList = commentMapper.replyPageQuery(commentPageDTO);
        if (commentDOList == null || commentDOList.isEmpty()) {
            CommentPageVO commentPageVO = new CommentPageVO();
            commentPageVO.setCommentVOS(Collections.emptyList());
            commentPageVO.setOffset(0);
            commentPageVO.setLastTime(commentPageDTO.getLastTime());
            return Results.success(commentPageVO);
        }
        List<CommentVO> commentVOList = new ArrayList<>();
        LocalDateTime minTime = null;
        int cou = 0;
        for (CommentDO commentDO : commentDOList) {
            if (minTime == null || commentDO.getCreateTime().equals(minTime)) {
                cou++;
                minTime = commentDO.getCreateTime();
            } else {
                minTime = commentDO.getCreateTime();
                cou = 1;
            }
            CommentVO commentVO = BeanUtil.copyProperties(commentDO, CommentVO.class);
            //TODO根据用户id查询用户基本信息
            ArrayList<Long> list1 = new ArrayList<>();
            list1.add(commentVO.getUid());
            List<UserRespDTO> userList = userMapper.getUserList(list1);
            commentVO.setUserRespDTO(userList.get(0));
            //判断当前用户是否点赞
            isLiked(commentVO);
            commentVOList.add(commentVO);
        }
        CommentPageVO commentPageVO = new CommentPageVO();
        commentPageVO.setCommentVOS(commentVOList);
        commentPageVO.setOffset(cou);
        commentPageVO.setLastTime(minTime);
        return Results.success(commentPageVO);
    }

    @Override
    public Result deleteById(Long id) {
        //判断是否是自己的评论
        CommentDO data = getById(id);
        if (UserContext.getUserId() == null) {
            return null;
        }
        if (Objects.equals(data.getUid(), UserContext.getUserId())) {
            removeById(id);
            return Results.success();
        }
        return Results.failure();

    }

    @Override
    @Transactional
    public Result<CommentDO> savaComment(CommentDTO commentDTO) {
        CommentDO commentDO = BeanUtil.copyProperties(commentDTO, CommentDO.class);
        commentDO.setUid(UserContext.getUserId());
        save(commentDO);
        postMapper.incrementCommentCount(commentDTO.getPostId());
        return Results.success(commentDO);
    }

    private void isLiked(CommentVO commentVO) {
        if (UserContext.getUserId() == null) {
            return;
        }
        String key = "check-chat:like:set:1" + commentVO.getId();
        Boolean member = stringRedisTemplate.opsForSet().isMember(key, UserContext.getUserId().toString());
        commentVO.setLiked(Boolean.TRUE.equals(member));
    }

}




